package de.wbh.gwt.form.layouter.shared.activity;

import java.util.List;

import javax.inject.Inject;

import com.allen_sauer.gwt.dnd.client.PickupDragController;
import com.google.gwt.activity.shared.AbstractActivity;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.inject.client.AsyncProvider;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.inject.assistedinject.Assisted;

import de.wbh.gwt.form.layouter.gwt.rpc.FieldServiceAsync;
import de.wbh.gwt.form.layouter.gwt.ui.view.widget.Field;
import de.wbh.gwt.form.layouter.shared.event.DragControllerAddedEvent;
import de.wbh.gwt.form.layouter.shared.event.DropControllerAddedEvent;

public class FieldsActivity extends AbstractActivity implements FieldsView.Presenter, FieldsCreatedEvent.Handler {

	private final AsyncProvider<FieldsView> viewProvider;

	private FieldsView view;

	private String selectedField;

	private EventBus eventBus;

	private final String efdName;

	private final FieldServiceAsync fieldService;

	private List<String> fieldIds;

	@Inject
	public FieldsActivity(AsyncProvider<FieldsView> viewProvider, FieldServiceAsync fieldService, @Assisted String efdName) {
		this.viewProvider = viewProvider;
		this.efdName = efdName;
		this.fieldService = fieldService;
	}

	@Override
	public void createField() {
		this.view.createField();
	}

	@Override
	public void fieldCreated(String result) {
		this.fieldIds.add(result);
		this.fieldService.updateEfd(this.efdName, this.fieldIds, new AsyncCallback<Void>() {
			@Override
			public void onFailure(Throwable caught) {
			}

			@Override
			public void onSuccess(Void result) {
			}
		});
		this.view.addField(result);
	}

	@Override
	public void onDragControllerAdded(final PickupDragController dragController) {
		Scheduler.get().scheduleDeferred(new Command() {

			@Override
			public void execute() {
				FieldsActivity.this.eventBus.fireEvent(new DragControllerAddedEvent(dragController));
			}
		});
	}

	@Override
	public void onFieldRemoved() {
		this.eventBus.fireEvent(new FieldRemovedEvent());
	}

	@Override
	public void onFieldsCreated(List<Field> fields) {
		this.view.onFieldsCreated(fields);
	}

	@Override
	public void removeFromEfd(String id) {
		this.fieldIds.remove(id);
		this.fieldService.updateEfd(this.efdName, this.fieldIds, new AsyncCallback<Void>() {
			@Override
			public void onFailure(Throwable caught) {
				//
			}

			@Override
			public void onSuccess(Void result) {
				//
			}
		});
	}

	@Override
	public void start(final AcceptsOneWidget panel, EventBus eventBus) {
		this.eventBus = eventBus;
		eventBus.addHandler(FieldsCreatedEvent.getType(), this);
		this.eventBus.addHandler(DropControllerAddedEvent.getType(), new DropControllerAddedEvent.Handler() {

			@Override
			public void onDropControllerAdded(DropControllerAddedEvent event) {
				if (FieldsActivity.this.view != null) {
					FieldsActivity.this.view.onDropControllerAdded(event.getDropController());
				}
			}
		});
		this.viewProvider.get(new AsyncCallback<FieldsView>() {

			@Override
			public void onFailure(Throwable caught) {
				caught.printStackTrace();
			}

			@Override
			public void onSuccess(FieldsView result) {
				FieldsActivity.this.view = result;
				FieldsActivity.this.view.setPresenter(FieldsActivity.this);
				panel.setWidget(FieldsActivity.this.view);

				FieldsActivity.this.fieldService.getFieldIds(FieldsActivity.this.efdName, new AsyncCallback<List<String>>() {
					@Override
					public void onFailure(Throwable caught) {
						caught.printStackTrace();
					}

					@Override
					public void onSuccess(List<String> fields) {
						FieldsActivity.this.fieldIds = fields;
						FieldsActivity.this.view.showFields(fields);
					}
				});
			}
		});
	}

}
